JS 有兩大類型別:原始型別 與 物件型別


#兩大類型別圖:

#原始型別(primitives):

#物件型別:

#如何判斷是不是物件(型別)?

  • 物件型別特質:可以自由擴增屬性。
//物件
const obj = {};
obj.age = 32;
console.log(obj); 

---- console區 ------
{age: 32}
//陣列 PS:實戰/平常中千萬不要這樣寫!!!!
const arr = [];
arr.age = '他今年滿18';
arr.push(18);
console.log(arr); 

---- console區 ------
[18, age: '他今年滿18']
//函式 把函式作為物件使用(實戰中可能見到)
const fn = function () {

}; 
fn.mySlogan = '我一個詭異的函式物件';
console.log(fn); 

---- console區 ------
//通常console.log無法看見函式內部內容
ƒ () {

}
---- console.dir()區 ------
這個方法可以看見物件型別中的內容
ƒ fn()
mySlogan: "我一個詭異的函式物件"
arguments: null
caller: null
length: 0
name: "fn"
//原始型別只有純值,無法拓增屬性
const num = 1;
    num.mySlogan = '今天是好天氣';
console.dir(num); 

---- console.dir區 ------
1

dir使用時機?25.00

型別方法在哪裡?

  • 原始型別的方法來自於-boxing-原始型別包裹物件:

    console.dir(String)
    //所有字串 數字型別方法都存在這
    ---- console.dir區 ------
    ƒ String()
    可以點選開發人員工具中顯示出的prototype:String屬性
    
  • 運作原理new operator://實戰千萬不要這樣寫

    • 以下由new來創建(物件):
      let str = new String(' 我是特別的 ');//這會是一個物件
      console.log(str)
      console.log(str.trim())
      ---- console區 ------
      String {' 我是特別的 '}
      我是特別的
      
let str2 = new String(' 我是特別的 ');
console.log(typeof str)
console.log(str == str2)
---- console區 ------
Object
false
//但這明明是兩個一樣的東西字串>純值>>變質了
-----------------------------

記住:str中存的原來是字串>原始型別>純值,無法拓增屬性,但是.....

str.myName = '加入了怪東東'
console.log(str)
---- console區 ------
String {' 我是特別的 ', myName: '加入了怪東東'}

#型別轉換(JS型別可以自由轉換)

#顯性轉換

  • 1-1:boxing-原型型別包裹物件 Number,String

    let price = 100; //number
      console.log(String(price)) //string
      console.log(BigInt(price))  //bigint
      console.log(Symbol(price))  //symbol(100)
    
  • 1-2:原型方法(要注意原型鍊中有沒有該方法/有沒有原始型別包裹物件)

      console.log(price.toString()) //string
       !!要注意原型鍊中有沒有該方法/有沒有原始型別包裹物件
       console.log(undefined.toString()) //TypeError
    
  • 1-3:數值型別相關方法

    console.log(Number('100元')) //NaN
    console.log(Number.parseInt('100元')) //100
    console.log(parseInt('100元')) //100
    因為在window全域物件下也有一個parseInt()的方法
    console.log(window.parseInt === Number.parseInt) //true
    
  • 3:正負運算子,正負一元運算子(一定會轉型成number)

    //二元運算子的例子:轉型成string
    console.log(1 + '1') //二元運算子轉型為string  '11'
    >>> `+`是運算子
    >>> 1是一個運算元
    >>> '1'是一個運算元
    這是二運算元
    
    //ㄧ元運算子的例子:轉型成number
    console.log(+ '1') //會轉型成number 1
    >>> `+`是運算子
    >>> '1'是一個運算元
    這是一運算元
    
    //ㄧ元運算子的例子:轉型成number
    console.log(+true) //會轉型成number 1
    
    //ㄧ元運算子的例子:轉型成number
    console.log(+'50元') //NaN
    NaN的型別是number
    
  • 2-2:邏輯 NOT 運算子(會轉型成boolean)

console.log(!true) //false
console.log(!false) //true

console.log(Boolean(0)) //先轉型成false
console.log(!0) //true 因為0是falsy value

console.log(Boolean('1')) //true
console.log(!'1') //false
console.log(!!'1') //true

隱性轉換(盡量不要去作隱性轉換)

    • 運算子(二元運算子)
      • 規則1:前後運算元,如果其中一個為字串型別,+就會被視為“字串運算子”
      • 規則2:前後運算元,如果無法轉成原始型別(那就是物件型別),+也會被視為“字串運算子”
      • 規則3:上述情況以外,+會被視為“算數運算子”
        console.log(100+100) //200 算數運算子
        console.log('我是'+'無敵') //'我是無敵' 字串運算子
        

練習:

console.log(1+'1') //"11" string +字串運算子
console.log(1+true) //2  number +算術運算子
console.log(1+ {}) //1[Object object] string +字串運算子
console.log(String({})) //[Object object]>>算數中,所有物件都是用String({})去做轉型所以會是 [Object Object]
console.log(1 + []) //"1" string +字串運算子
console.log(1 + [1,2,3]) //"11,2,3" string +字串運算子
console.log(1+ {a:1}) //1[Object Object]
特例:bigInt無法和其他型別/數字直接作轉換
console.log(1 + 1n) //error
特例:symbol()
console.log(1 + symbol(1)) //cannot a symbol value to a number
console.log( '1' + symbol(1)) //cannot a symbol value to a string
console.log({} + symbol(1)) //cannot a symbol value to a string
特例:bigInt無法和其他數值直接作轉換
console.log(1 + 1n) //error
  • 算術運算子(- / * )
    console.log(1 - '1') //0 number
    console.log(100 * true) //100 number
    console.log(100 - true) //99 number
    
    ### 例外狀況 BigInt
    console.log(1n * 100);

其他類型比較

console.log([100] * 100); //10000 number
console.log([100,1] * 100);// NaN
//陣列轉型
console.log([100].toString());
console.log([10, 0].toString()); // 10 ,0
console.log(Number([10, 0].toString())); // NaN

型別比較

1.寬鬆相等:值相等,型別 不需要
console.log(1 == '1'); //true

  • Number Strung Boolean 這三個進行比對時,都會以Number進行轉型

    console.log("1" == true) // true
    console.log(1 == "1") // true
    console.log("0" == false) // true
    
  • null,undefined 不轉型(都是false),但null與undefined兩者相比都是true

    cosole.log(null == 0) //false
    cosole.log(null == '') //false
    cosole.log(null == false) //false
    console.log(null == undefined) //true
    console.log(null == null) //true
    console.log(undefined == undefined) //true
    
  • 物件與非物件比對:物件與其他類型比對時,會透過“boxing包裹物件”將物件轉為相同型別
    //使用原始型別包裹物件作轉型
    console.log([0] == 0) //true
    console.log('[object object]' == {}) //true 因為String({}) [object object]
    console.log(['a'] == 'a') //true
    
  • 1:布林採用Number轉型
    console.log([] == false); //true Number([]) >> 0 >>falsy value
    console.log([1] == true) //true
    console.log([2] == true) //false
    
  • 2:陣列轉數值,會先toString()再套用Number
  • 3: 例外冷門:
    let sym1 = Symbol(1)
    let sym2 = Symbol(1)
    console.log(sym1 == sym2) // false
    
  • 例外:Bigint,轉為數學值,沒有NaN,沒有小數點,沒有最大值其他概念與Number接近
    console.log(Number.MAX_SAFE_INTEGER) //9007199254740991
    console.log(9007199254740991 == '9007199254740991') //true
    console.log(9007199254740993 == '9007199254740992') //true >>>已經超過最大安全數值,因此比對結果有問題
    console.log(9007199254740993n == '9007199254740992') //false 超過安全數值之後,有加入BigInt相對在比對上是穩定的
    console.log(9007199254740993n == '9007199254740993') //true 超過安全數值之後,有加入BigInt相對在比對上是穩定的
    console.log(100n * 100n) //10000n
    

2.嚴格相等:值 與 型別 完全相同 (開發使用這個)
console.log(1 === '1'); //false

3.嚴格相等有例外狀況

//false版
console.log(NaN === NaN); //false
console.log(undefined === null); //false
console.log({} === {}); //false
console.log([] === []); //false
console.log(new Number(0) === new Number(0)); //false
原理是記憶體位址指向不同
//true版
console.log(+0 === -0); //true
console.log(Infinite === Infinite); //true

真假值(待補充)

筆記來源:

  • <js直播工程師養成班-六角學院>
  • <javascript 核心篇-六角學院>
#六角學院 javascript 六角學院-js直播養成班 js核心篇







你可能感興趣的文章

1731. The Number of Employees Which Report to Each Employee

1731. The Number of Employees Which Report to Each Employee

Laravel view component cache

Laravel view component cache

Vue3-新增產品(查/增/修/刪)功能實作

Vue3-新增產品(查/增/修/刪)功能實作






留言討論